// g++ -o thread_pool1 thread_pool1.cc -std=c++14
// ./thread_pool1
#include <atomic>
#include <condition_variable>
#include <future>
#include <iostream>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
using namespace std;
class ThreadPool {
 public:
  ThreadPool(int n) : thread_num_(n) {}
  ~ThreadPool() {
    for (const auto& t : threads_) t->join();
  }
  void Start();
  void AddTask();

  void ThreadFunc();

 private:
  static int max_task_size;
  std::vector<std::unique_ptr<std::thread>> threads_;
  std::queue<int> task_que_;
  std::mutex mtx_;
  std::condition_variable empty_cond_;
  std::condition_variable full_cond_;
  int thread_num_;
};
void ThreadPool::Start() {
  for (int i = 0; i < thread_num_; i++) {
    threads_.push_back(
        make_unique<std::thread>(std::bind(&ThreadPool::ThreadFunc, this)));
  }
}
void ThreadPool::AddTask() {
  std::unique_lock<std::mutex> ul(mtx_);
  while (task_que_.size() == max_task_size) {
    full_cond_.wait(ul);
  }
  task_que_.push(1);
  empty_cond_.notify_one();
}
void ThreadPool::ThreadFunc() {
  std::unique_lock<std::mutex> ul(mtx_);
  while (task_que_.empty()) {
    empty_cond_.wait(ul);
  }
  task_que_.pop();
  // 处理
  std::cout << "处理完毕一个任务" << std::endl;
  full_cond_.notify_all();
}
int ThreadPool::max_task_size = 5;
int main() {
  ThreadPool p(4);
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.AddTask();
  p.Start();

  return 0;
}